package org.microframework.cloud.system.controller;

import java.util.Date;
import java.util.List;
import java.util.UUID;
import org.microframework.base.core.datasource.annotation.Tx;
import org.microframework.base.core.domain.R;
import org.microframework.cloud.system.model.domain.Role;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;

/**
 * 角色管理控制器
 * 使用JFinal ActiveRecord实现数据访问
 */
@Slf4j
@RestController
@RequestMapping("/api/roles")
@Tag(name = "角色管理", description = "角色管理相关接口")
public class RoleController {

    /**
     * 获取角色列表
     * 使用JFinal Db.find方法
     */
    @GetMapping
    @Operation(summary = "获取角色列表")
    public R<List<Record>> list() {
        List<Record> roles = Db.find("SELECT id, role_name as name, role_key as `key`, status, create_time, remark FROM sys_role WHERE del_flag = 0");
        return R.ok(roles);
    }
    
    /**
     * 获取角色详情
     * 使用JFinal Model.findById方法
     */
    @GetMapping("/{id}")
    @Operation(summary = "获取角色详情")
    public R<?> get(@PathVariable("id") String id) {
        Role role = Role.dao.findById(id);
            
        if (role == null) {
            return R.fail("角色不存在");
        }
        
        return R.ok(role);
    }
    
    /**
     * 创建角色
     * 使用JFinal ActiveRecord的save方法
     */
    @PostMapping
    @Operation(summary = "创建角色")
    public R<?> create(@RequestBody Role roleReq) {
        // 检查角色标识是否存在
        Record existingRole = Db.findFirst("SELECT id FROM sys_role WHERE role_key = ? AND del_flag = 0", roleReq.getRoleKey());
        if (existingRole != null) {
            return R.fail("角色标识已存在");
        }
        
        // 创建角色
        Role role = new Role();
            
        role.setId(UUID.randomUUID().toString().replace("-", ""));
        role.setRoleName(roleReq.getRoleName());
        role.setRoleKey(roleReq.getRoleKey());
        role.setStatus(0); // 默认启用
        role.setDelFlag(0); // 未删除
        role.setCreateTime(new Date());
        role.setCreateBy("admin");
        role.setRemark(roleReq.getRemark());
        
        // 保存角色
        boolean success = role.save();
        
        if (success) {
            return R.ok();
        } else {
            return R.fail("创建角色失败");
        }
    }
    
    /**
     * 更新角色
     * 使用JFinal ActiveRecord的update方法
     */
    @PutMapping("/{id}")
    @Operation(summary = "更新角色")
    public R<?> update(@PathVariable("id") String id, @RequestBody Role roleReq) {
        // 查询角色
        Role role = Role.dao.findById(id);
            
        if (role == null) {
            return R.fail("角色不存在");
        }
        
        // 检查角色标识是否重复
        if (!role.getRoleKey().equals(roleReq.getRoleKey())) {
            Record existingRole = Db.findFirst("SELECT id FROM sys_role WHERE role_key = ? AND del_flag = 0 AND id != ?", 
                    roleReq.getRoleKey(), id);
            if (existingRole != null) {
                return R.fail("角色标识已存在");
            }
        }
        
        // 更新角色信息
        role.setRoleName(roleReq.getRoleName());
        role.setRoleKey(roleReq.getRoleKey());
        if (roleReq.getStatus() != null) {
            role.setStatus(roleReq.getStatus());
        }
        role.setUpdateTime(new Date());
        role.setUpdateBy("admin");
        role.setRemark(roleReq.getRemark());
        
        // 更新角色
        boolean success = role.update();
        
        if (success) {
            return R.ok();
        } else {
            return R.fail("更新角色失败");
        }
    }
    
    /**
     * 删除角色（逻辑删除）
     * 使用JFinal Db.update方法
     */
    @DeleteMapping("/{id}")
    @Operation(summary = "删除角色")
    public R<?> delete(@PathVariable("id") String id) {
        // 检查角色是否已分配给用户
        List<Record> userRoles = Db.find("SELECT user_id FROM sys_user_role WHERE role_id = ?", id);
        if (userRoles != null && !userRoles.isEmpty()) {
            return R.fail("角色已分配给用户，无法删除");
        }
        
        // 逻辑删除角色
        int affected = Db.update("UPDATE sys_role SET del_flag = 1, update_time = ?, update_by = ? WHERE id = ?", 
                new Date(), "admin", id);
                
        if (affected > 0) {
            return R.ok();
        } else {
            return R.fail("删除角色失败");
        }
    }
    
    /**
     * 分配菜单权限
     * 使用JFinal事务注解和批量操作
     */
    @PostMapping("/{id}/menus")
    @Operation(summary = "分配菜单权限")
    @Tx
    public R<?> assignMenus(@PathVariable("id") String roleId, @RequestBody List<String> menuIds) {
        try {
            // 删除原有关联
            Db.update("DELETE FROM sys_role_menu WHERE role_id = ?", roleId);
            
            if (menuIds != null && !menuIds.isEmpty()) {
                // 批量插入新关联
                String sql = "INSERT INTO sys_role_menu (menu_id, role_id) VALUES (?, ?)";
                
                // 批量处理参数
                Object[][] batchParams = new Object[menuIds.size()][2];
                for (int i = 0; i < menuIds.size(); i++) {
                    batchParams[i][0] = menuIds.get(i);
                    batchParams[i][1] = roleId;
                }
                
                // 使用批量插入提高性能
                int[] result = Db.batch(sql, batchParams, menuIds.size());
                
                log.info("为角色[{}]分配了{}个菜单权限", roleId, result.length);
            }
            
            return R.ok();
        } catch (Exception e) {
            log.error("分配菜单权限失败", e);
            throw e; // 抛出异常触发事务回滚
        }
    }
    
    /**
     * 获取角色的菜单ID列表
     * 使用JFinal Db.query方法
     */
    @GetMapping("/{id}/menus")
    @Operation(summary = "获取角色的菜单ID列表")
    public R<List<String>> getRoleMenus(@PathVariable("id") String roleId) {
        List<String> menuIds = Db.query("SELECT menu_id FROM sys_role_menu WHERE role_id = ?", roleId);
        return R.ok(menuIds);
    }
    
    /**
     * 获取角色的用户列表
     * 使用JFinal Db.find方法
     */
    @GetMapping("/{id}/users")
    @Operation(summary = "获取角色的用户列表")
    public R<List<Record>> getRoleUsers(@PathVariable("id") String roleId) {
        List<Record> users = Db.find("SELECT u.id, u.username, u.nickname, u.email, u.mobile, u.status " +
                "FROM sys_user u " +
                "INNER JOIN sys_user_role ur ON u.id = ur.user_id " +
                "WHERE ur.role_id = ? AND u.del_flag = 0", roleId);
        return R.ok(users);
    }
} 